import { BaseService } from './base.service'
import { Sheet, User, Cell, SheetMember, MemberRole } from '@/types/sheet'
import { ServiceRegistry } from './base.service'
import { MemberRole as PrismaMemberRole } from '@prisma/client'

export interface CreateSheetData {
  title: string
  description?: string
  ownerId: string
}

export interface UpdateSheetData {
  title?: string
  description?: string
  isPublic?: boolean
  allowEdit?: boolean
}

export interface SheetWithDetails extends Sheet {
  owner: User
  members: Array<SheetMember & { user: User }>
  cells: Cell[]
}

export interface SheetPermission {
  canView: boolean
  canEdit: boolean
  canDelete: boolean
  canShare: boolean
}

export class SheetService extends BaseService {
  constructor() {
    super()
    ServiceRegistry.getInstance().register('sheet', this)
  }

  // 创建表格
  async createSheet(data: CreateSheetData): Promise<Sheet> {
    return await this.executeWithResilience(async () => {
      const sheet = await this.prisma.sheet.create({
        data: {
          title: data.title,
          description: data.description,
          ownerId: data.ownerId
        },
        include: {
          owner: true,
          members: {
            include: {
              user: true
            }
          },
          cells: true
        }
      })
      
      // 转换 null 为 undefined 以匹配类型
      return {
        ...sheet,
        description: sheet.description ?? undefined,
        shareToken: sheet.shareToken ?? undefined
      } as Sheet
    })
  }

  // 获取表格详情
  async getSheetById(id: string): Promise<SheetWithDetails | null> {
    return await this.executeWithResilience(async () => {
      const sheet = await this.prisma.sheet.findUnique({
        where: { id },
        include: {
          owner: true,
          members: {
            include: {
              user: true
            }
          },
          cells: {
            orderBy: [
              { row: 'asc' },
              { column: 'asc' }
            ]
          }
        }
      })
      
      if (!sheet) return null
      
      // 转换类型以匹配 SheetWithDetails
      return {
        ...sheet,
        description: sheet.description ?? undefined,
        shareToken: sheet.shareToken ?? undefined,
        owner: {
          ...sheet.owner,
          avatar: sheet.owner.avatar ?? undefined
        },
        members: sheet.members.map(member => ({
          ...member,
          user: {
            ...member.user,
            avatar: member.user.avatar ?? undefined
          }
        }))
      } as SheetWithDetails
    })
  }

  // 获取用户的表格列表
  async getUserSheets(userId: string): Promise<SheetWithDetails[]> {
    return await this.executeWithResilience(async () => {
      const sheets = await this.prisma.sheet.findMany({
        where: {
          OR: [
            { ownerId: userId },
            {
              members: {
                some: { userId }
              }
            }
          ]
        },
        include: {
          owner: true,
          members: {
            include: {
              user: true
            }
          },
          cells: {
            take: 100, // 限制返回的单元格数量以提高性能
            orderBy: [
              { row: 'asc' },
              { column: 'asc' }
            ]
          }
        },
        orderBy: { updatedAt: 'desc' }
      })
      
      // 转换类型以匹配 SheetWithDetails
      return sheets.map(sheet => ({
        ...sheet,
        description: sheet.description ?? undefined,
        shareToken: sheet.shareToken ?? undefined,
        owner: {
          ...sheet.owner,
          avatar: sheet.owner.avatar ?? undefined
        },
        members: sheet.members.map(member => ({
          ...member,
          user: {
            ...member.user,
            avatar: member.user.avatar ?? undefined
          }
        }))
      })) as SheetWithDetails[]
    })
  }

  // 更新表格信息
  async updateSheet(id: string, data: UpdateSheetData): Promise<Sheet> {
    return await this.executeWithResilience(async () => {
      const sheet = await this.prisma.sheet.update({
        where: { id },
        data: {
          ...data,
          updatedAt: new Date()
        },
        include: {
          owner: true,
          members: {
            include: {
              user: true
            }
          },
          cells: true
        }
      })
      
      // 转换类型以匹配 Sheet
      return {
        ...sheet,
        description: sheet.description ?? undefined,
        shareToken: sheet.shareToken ?? undefined,
        owner: {
          ...sheet.owner,
          avatar: sheet.owner.avatar ?? undefined
        },
        members: sheet.members.map(member => ({
          ...member,
          user: {
            ...member.user,
            avatar: member.user.avatar ?? undefined
          }
        }))
      } as Sheet
    })
  }

  // 删除表格
  async deleteSheet(id: string): Promise<void> {
    await this.executeWithResilience(async () => {
      await this.prisma.sheet.delete({
        where: { id }
      })
    })
  }

  // 检查用户权限
  async checkUserPermission(
    sheetId: string, 
    userId: string
  ): Promise<SheetPermission> {
    const sheet = await this.getSheetById(sheetId)
    
    if (!sheet) {
      return {
        canView: false,
        canEdit: false,
        canDelete: false,
        canShare: false
      }
    }

    const isOwner = sheet.ownerId === userId
    const membership = sheet.members?.find(m => m.userId === userId)
    const role = membership?.role

    return {
      canView: isOwner || !!membership || sheet.isPublic,
      canEdit: isOwner || role === MemberRole.EDITOR || role === MemberRole.OWNER,
      canDelete: isOwner,
      canShare: isOwner || role === MemberRole.OWNER
    }
  }

  // 添加成员
  async addMember(
    sheetId: string, 
    userId: string, 
    role: MemberRole = MemberRole.VIEWER
  ): Promise<SheetMember> {
    return await this.executeWithResilience(async () => {
      const member = await this.prisma.sheetMember.create({
        data: {
          sheetId,
          userId,
          role: role as PrismaMemberRole
        },
        include: {
          user: true
        }
      })
      
      // 转换类型以匹配 SheetMember
      return {
        ...member,
        user: {
          ...member.user,
          avatar: member.user.avatar ?? undefined
        }
      } as SheetMember
    })
  }

  // 移除成员
  async removeMember(sheetId: string, userId: string): Promise<void> {
    await this.executeWithResilience(async () => {
      await this.prisma.sheetMember.deleteMany({
        where: {
          sheetId,
          userId
        }
      })
    })
  }

  // 更新成员角色
  async updateMemberRole(
    sheetId: string, 
    userId: string, 
    role: MemberRole
  ): Promise<SheetMember> {
    return await this.executeWithResilience(async () => {
      const member = await this.prisma.sheetMember.update({
        where: {
          userId_sheetId: {
            userId,
            sheetId
          }
        },
        data: { role: role as PrismaMemberRole },
        include: {
          user: true
        }
      })
      
      // 转换类型以匹配 SheetMember
      return {
        ...member,
        user: {
          ...member.user,
          avatar: member.user.avatar ?? undefined
        }
      } as SheetMember
    })
  }

  // 批量保存单元格
  async saveCells(sheetId: string, cells: Cell[]): Promise<void> {
    await this.executeTransaction(async (tx) => {
      // 删除现有单元格
      await tx.cell.deleteMany({
        where: { sheetId }
      })

      // 批量插入新单元格
      if (cells.length > 0) {
        await tx.cell.createMany({
          data: cells.map(cell => ({
            sheetId,
            row: cell.row,
            column: cell.column,
            value: cell.value || '',
            formula: cell.formula || null,
            style: cell.style || null
          }))
        })
      }

      // 更新表格的更新时间
      await tx.sheet.update({
        where: { id: sheetId },
        data: { updatedAt: new Date() }
      })
    })
  }

  // 获取表格的单元格数据
  async getSheetCells(sheetId: string): Promise<Cell[]> {
    return await this.executeWithResilience(async () => {
      const cells = await this.prisma.cell.findMany({
        where: { sheetId },
        orderBy: [
          { row: 'asc' },
          { column: 'asc' }
        ]
      })
      
      // 转换类型以匹配 Cell
      return cells.map(cell => ({
        ...cell,
        value: cell.value ?? undefined,
        formula: cell.formula ?? undefined,
        style: cell.style as any ?? undefined
      })) as Cell[]
    })
  }

  // 更新单个单元格
  async updateCell(
    sheetId: string, 
    row: number, 
    column: number, 
    value: string, 
    formula?: string, 
    style?: any
  ): Promise<Cell> {
    return await this.executeWithResilience(async () => {
      const cell = await this.prisma.cell.upsert({
        where: {
          sheetId_row_column: {
            sheetId,
            row,
            column
          }
        },
        update: {
          value,
          formula: formula || null,
          style: style || null,
          updatedAt: new Date()
        },
        create: {
          sheetId,
          row,
          column,
          value,
          formula: formula || null,
          style: style || null
        }
      })
      
      // 转换类型以匹配 Cell
      return {
        ...cell,
        value: cell.value ?? undefined,
        formula: cell.formula ?? undefined,
        style: cell.style as any ?? undefined
      } as Cell
    })
  }

  // 通过分享token获取表格
  async getSheetByShareToken(token: string): Promise<SheetWithDetails | null> {
    return await this.executeWithResilience(async () => {
      const sheet = await this.prisma.sheet.findUnique({
        where: { shareToken: token },
        include: {
          owner: true,
          members: {
            include: {
              user: true
            }
          },
          cells: {
            orderBy: [
              { row: 'asc' },
              { column: 'asc' }
            ]
          }
        }
      })
      
      if (!sheet) return null
      
      // 转换类型以匹配 SheetWithDetails
      return {
        ...sheet,
        description: sheet.description ?? undefined,
        shareToken: sheet.shareToken ?? undefined,
        owner: {
          ...sheet.owner,
          avatar: sheet.owner.avatar ?? undefined
        },
        members: sheet.members.map(member => ({
          ...member,
          user: {
            ...member.user,
            avatar: member.user.avatar ?? undefined
          }
        }))
      } as SheetWithDetails
    })
  }

  // 生成分享token
  async generateShareToken(sheetId: string): Promise<string> {
    const token = `share_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
    
    await this.executeWithResilience(async () => {
      await this.prisma.sheet.update({
        where: { id: sheetId },
        data: { shareToken: token }
      })
    })
    
    return token
  }

  // 删除分享token
  async removeShareToken(sheetId: string): Promise<void> {
    await this.executeWithResilience(async () => {
      await this.prisma.sheet.update({
        where: { id: sheetId },
        data: { shareToken: null }
      })
    })
  }
}
